package per.example.arpproject.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 *
 * @author tanghongfeng
 */
public final class DateUtil {
    public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String DATETIME_PATTERN = "yyyyMMddHHmmss";
    public static final String DATETIME_MS_PATTERN = "yyyyMMddHHmmssSSS";
    public static final String DATE_PATTERN = "yyyyMMdd";
    public static final String DATE_LONG_PATTERN = "yyyy-MM-dd";
  
    public static final int DATE = Calendar.DATE;
    public static final int HOUR = Calendar.HOUR;
    public static final int MINUTE = Calendar.MINUTE;
    public static final int SECOND = Calendar.SECOND;

    /**
     * 零点时刻
     *
     * @param dateTime 日期
     * @return 零点时刻
     */
    public static Date zeroDate(Date dateTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dateTime);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    public static Date zeroDate(LocalDateTime localDateTime) {
        Date date = localDateTime2Date(localDateTime);
        return zeroDate(date);
    }

    /**
     * 半夜时分
     *
     * @param dateTime 日期
     * @return 半夜时分
     */
    public static Date midnight(Date dateTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dateTime);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    public static Date midnight(LocalDateTime dateTime) {
        return midnight(localDateTime2Date(dateTime));
    }

    /**
     * 过去某天
     *
     * @param dataTime 日期
     * @param days     过去某天
     * @return
     */
    public static LocalDateTime dateMinus(LocalDateTime dataTime, long days) {
        if (null == dataTime) {
            dataTime = LocalDateTime.now();
        }

        return dataTime.minusDays(days);
    }

    /**
     * LocalDateTime 转换为 Date.
     *
     * @param localDateTime
     * @param zoneId        time-zone ID, 如果没有指定，使用系统默认的 ZoneId
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime, String zoneId) {
        ZoneId zone = StringUtils.isBlank(zoneId) ? ZoneId.systemDefault() : ZoneId.of(zoneId);
        ZonedDateTime zdt = localDateTime.atZone(zone);
        return Date.from(zdt.toInstant());
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        return localDateTime2Date(localDateTime, null);
    }

    /**
     * Date 转换为 LocalDateTime
     *
     * @param date
     * @param zoneId time-zone ID, 如果没有指定，使用系统默认的 ZoneId
     */
    public static LocalDateTime date2LocalDateTime(Date date, String zoneId) {
        Instant instant = date.toInstant();
        ZoneId zone = StringUtils.isBlank(zoneId) ? ZoneId.systemDefault() : ZoneId.of(zoneId);
        return instant.atZone(zone).toLocalDateTime();
    }

    public static LocalDateTime date2LocalDateTime(Date date) {
        return date2LocalDateTime(date, null);
    }

    /**
     * 格式化，默认格式：yyyy-MM-dd HH:mm:ss
     *
     * @param date    日期
     * @param pattern 日期格式
     * @return
     */
    public static String format(Date date, String pattern) {
        if (StringUtils.isBlank(pattern)) {
            pattern = DATE_TIME_PATTERN;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * localDateTime格式化
     * @param localDateTime    日期
     * @param pattern 日期格式
     * @return
     */
    public static String localDateTimeFormat(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter dtf=DateTimeFormatter.ofPattern(pattern);
        return localDateTime.format(dtf);
    }

    /**
     * 判断日期是否是同一天
     *
     * @param src
     * @param dest
     * @return
     */
    public static boolean isSameDay(Date src, Date dest) {
        LocalDateTime srcDateTime = date2LocalDateTime(src);
        int srcDay = srcDateTime.getDayOfMonth();

        LocalDateTime destDateTime = date2LocalDateTime(dest);
        int destDay = destDateTime.getDayOfMonth();

        return srcDay == destDay;
    }

    public static boolean isSameMonth(Date src, Date dest) {
        LocalDateTime srcDateTime = date2LocalDateTime(src);
        final int srcMonth = srcDateTime.getMonthValue();

        final LocalDateTime destDateTime = date2LocalDateTime(dest);
        final int destMonth = destDateTime.getMonthValue();

        return srcMonth == destMonth;
    }

    /**
     * 获取默认格式的时间字符串 yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getCurrentTime() {
        return format(new Date(), DATE_TIME_PATTERN);
    }

    /**
     * 获取默认短格式的时间字符串
     * yyyyMMdd
     *
     * @return
     */
    public static String getCurrentShortDate() {
        return format(new Date(), DATE_PATTERN);
    }

    /**
     * 获取默认短格式的时间字符串
     * yyyyMMddHHmmss
     *
     * @return
     */
    public static String getCurrentShortTime() {
        return format(new Date(), DATETIME_PATTERN);
    }

    /**
     * 日期运算
     *
     * @param date
     * @param value 增加的时间，负数即为减
     * @param field 单位
     * @return
     */
    public static Date add(Date date, int value, int field) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int fieldNewValue = (c.get(field) + value);
        c.set(field, fieldNewValue);
        return c.getTime();
    }

    /**
     * 获取当本周星期一 0点0时0分
     *
     * @return
     */
    public static Date getMonday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        //Calendar 一周为周日到周六，所有当前日期减1
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1); 
        //更新时间
        calendar.getTime(); 
        //第一天为星期日
        calendar.set(Calendar.DAY_OF_WEEK, 2); 
        return zeroDate(calendar.getTime());
    }

    /**
     * 字符串转时间
     * @param dateStr 时间字符串
     * @param pattern 时间格式
     * @return
     */
    public static Date stringToDate(String dateStr,String pattern){
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    public static String timeStamp2Date(Long timeLong) {
    	//要转换的时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date;
        try {
            date = sdf.parse(sdf.format(timeLong));
            return sdf.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static String getDateString(String datePattern) {
        return new SimpleDateFormat(datePattern).format(new Date());
    }

    public static void main(String[] args) {
//        System.out.println(getMonday());
        LocalDateTime t=LocalDateTime.now();
        System.out.println(localDateTimeFormat(t,DATE_TIME_PATTERN));

    }
}
